package com.github.binarywang.demo.wechat.controller;

import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.github.binarywang.demo.wechat.utils.JsonUtils;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaMessage;
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;

@RestController
@RequestMapping({ "/wechat/portal" })
public class WxPortalController {
	private final Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	private WxMaService wxService;

	@Autowired
	private WxMaMessageRouter router;

	@GetMapping(produces = { "text/plain;charset=utf-8" })
	public String authGet(
			@org.springframework.web.bind.annotation.RequestParam(name = "signature", required = false) String signature,
			@org.springframework.web.bind.annotation.RequestParam(name = "timestamp", required = false) String timestamp,
			@org.springframework.web.bind.annotation.RequestParam(name = "nonce", required = false) String nonce,
			@org.springframework.web.bind.annotation.RequestParam(name = "echostr", required = false) String echostr) {
		this.logger.info("\n接收到来自微信服务器的认证消息：signature = [{}], timestamp = [{}], nonce = [{}], echostr = [{}]",
				new Object[] { signature, timestamp, nonce, echostr });
		if (StringUtils.isAnyBlank(new CharSequence[] { signature, timestamp, nonce, echostr })) {
			throw new IllegalArgumentException("请求参数非法，请核实!");
		}
		System.err.println(JsonUtils.toJson(this.wxService.getWxMaConfig().getToken()));
		if (this.wxService.checkSignature(timestamp, nonce, signature)) {
			return echostr;
		}

		return "非法请求";
	}

	@PostMapping(produces = { "application/xml; charset=UTF-8" })
	public String post(@RequestBody String requestBody,
			@org.springframework.web.bind.annotation.RequestParam("msg_signature") String msgSignature,
			@org.springframework.web.bind.annotation.RequestParam("encrypt_type") String encryptType,
			@org.springframework.web.bind.annotation.RequestParam("signature") String signature,
			@org.springframework.web.bind.annotation.RequestParam("timestamp") String timestamp,
			@org.springframework.web.bind.annotation.RequestParam("nonce") String nonce) {
		this.logger.info(
				"\n接收微信请求：[msg_signature=[{}], encrypt_type=[{}], signature=[{}], timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
				new Object[] { msgSignature, encryptType, signature, timestamp, nonce, requestBody });

		boolean isJson = Objects.equals(this.wxService.getWxMaConfig().getMsgDataFormat(), "JSON");
		WxMaMessage inMessage;
		if (StringUtils.isBlank(encryptType)) {
			if (isJson) {
				inMessage = WxMaMessage.fromJson(requestBody);
			} else {
				inMessage = WxMaMessage.fromXml(requestBody);
			}
			route(inMessage);
			return "success";
		}

		if ("aes".equals(encryptType)) {
			if (isJson) {
				inMessage = WxMaMessage.fromEncryptedJson(requestBody, this.wxService.getWxMaConfig());
			} else {
				inMessage = WxMaMessage.fromEncryptedXml(requestBody, this.wxService.getWxMaConfig(), timestamp, nonce,
						msgSignature);
			}
			route(inMessage);
			return "success";
		}

		throw new RuntimeException("不可识别的加密类型：" + encryptType);
	}

	private void route(WxMaMessage message) {
		try {
			this.router.route(message);
		} catch (Exception e) {
			this.logger.error(e.getMessage(), e);
		}
	}
}
